package com.guanghua.brick.html.export;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.guanghua.brick.html.Constant;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;

public class ExportToExcelResult implements Result {
	
	private static Log logger = LogFactory.getLog(ExportToExcelResult.class);


	public void execute(ActionInvocation action) throws Exception {
		//获取执行的方法
		String m = action.getProxy().getMethod();
		m = (m!=null)?m:"execute";
		Method method = action.getAction().getClass().getMethod(m, (Class[])null);
			
		//export的annotation
		Export e = null;
		if (method != null) e = (Export)method.getAnnotation(Export.class);
		String value = e.value();
		logger.trace("export action' data set key:" + value);
		
		//文件名
		String name = e.fileName();
		if (name == null || name.length() == 0) name = action.getInvocationContext().getName();
		name += ".xls";
		logger.trace("export file name:" + name);
		
		//需要导出的列
		String exportKey = ServletActionContext.getRequest().getParameter(Constant.GLOBE_EXPORT_KEY);
		String exportDisplay = ServletActionContext.getRequest().getParameter(Constant.GLOBE_EXPORT_DISPLAY);
		if (exportDisplay == null || exportDisplay.length() == 0) exportDisplay = exportKey;
		logger.trace("export file keys:" + exportKey);
		logger.trace("export file columns:" + exportDisplay);
		
		//分拆
		String[] columnName = exportDisplay.split(",");
		String[] columnKey = exportKey.split(",");
		
		//获取数据集
		Collection data = (Collection)ServletActionContext.getRequest().getAttribute(value);
		
		//调用创建excel流的方法
		HttpServletResponse response = ServletActionContext.getResponse();
		ServletOutputStream sos = response.getOutputStream();
		//设定http头
		response.setHeader("content-type", "application");
		//response.setHeader("Accept-Ranges", "bytes");
		response.setBufferSize(1024*1024);
		response.setHeader("content-disposition", "attachment;filename=" + new String(name.getBytes("GBK"), "iso-8859-1"));
		
		
		//导出
		createExportingExcel(sos, data, columnName, columnKey, null, false, new HashMap<String, String>());
		
		//将生成的到处的流flush道客户端
		sos.flush();
		sos.close();
	}
	
	
	private void createExportingExcel(OutputStream os, Collection data, String[] heads, String[] keys, String[] widths, boolean seq, Map<String, String> paramContent) {
		try {
			//生成excel
			WritableWorkbook workbook = Workbook.createWorkbook(os);
			WritableSheet sheet = workbook.createSheet("Sheet1", 0);
			
			//测试的操作			
			//sheet.getSettings().setScaleFactor();//设定缩放大小
			//sheet.getSettings().setShowGridLines(true)//设置是否需要显示grid line

			
			//打印相关操作
//			sheet.getSettings().setPrintGridLines(true);
//			if ("true".equals(paramContent.get(EXPORT_LANDSCAPE)))
//				sheet.getSettings().setOrientation(PageOrientation.LANDSCAPE);
//			//打印编号和标题头
//			if ("true".equals(paramContent.get(EXPORT_PRINTNO)))
//				sheet.getSettings().setPrintHeaders(true);
//			
//			//在多少页中显示所有列
//			if (paramContent.get(EXPORT_FITWIDTH) != null)
//				sheet.getSettings().setFitWidth(Integer.parseInt(paramContent.get(EXPORT_FITWIDTH).toString()));
//			//在多少页中显示所有行
//			if (paramContent.get(EXPORT_FITHEIGHT) != null)
//				sheet.getSettings().setFitHeight(Integer.parseInt(paramContent.get(EXPORT_FITHEIGHT).toString()));
//			
//			//边距
//			if (paramContent.get(EXPORT_TOP) != null)
//				sheet.getSettings().setTopMargin(Double.parseDouble(paramContent.get(EXPORT_TOP).toString()));
//			if (paramContent.get(EXPORT_BOTTOM) != null)
//				sheet.getSettings().setBottomMargin(Double.parseDouble(paramContent.get(EXPORT_BOTTOM).toString()));
//			if (paramContent.get(EXPORT_LEFT) != null)
//				sheet.getSettings().setLeftMargin(Double.parseDouble(paramContent.get(EXPORT_LEFT).toString()));
//			if (paramContent.get(EXPORT_RIGHT) != null)
//				sheet.getSettings().setRightMargin(Double.parseDouble(paramContent.get(EXPORT_RIGHT).toString()));			
//			
//			//页眉
//			if (paramContent.get(EXPORT_HEADER) != null) {
//				HeaderFooter hf = new HeaderFooter();
//				hf.getCentre().append(paramContent.get(EXPORT_HEADER).toString());
//				
//				sheet.getSettings().setHeader(hf);
//			}
//			if (paramContent.get(EXPORT_HMARGIN) != null)
//				sheet.getSettings().setHeaderMargin(Double.parseDouble(paramContent.get(EXPORT_HMARGIN).toString()));
//
//			//页脚
//			if (paramContent.get(EXPORT_FOOTER) != null) {
//				HeaderFooter hf = new HeaderFooter();
//				hf.getCentre().append("第");
//				hf.getCentre().appendPageNumber();
//				hf.getCentre().append("页 共");
//				hf.getCentre().appendTotalPages();
//				hf.getCentre().append("页");
//				
//				//hf.getLeft().append("制作人:");
//				hf.getLeft().append(paramContent.get(EXPORT_FOOTER).toString());
//				
//				hf.getRight().appendDate();
//				hf.getRight().append(" ");
//				hf.getRight().appendTime();
//				
//				sheet.getSettings().setFooter(hf);
//			}
//
//			if (paramContent.get(EXPORT_FMARGIN) != null)
//				sheet.getSettings().setFooterMargin(Double.parseDouble(paramContent.get(EXPORT_FMARGIN).toString()));
			
			//写表头
			for (int i = 0; heads != null && i < heads.length; i ++) {
				WritableFont headFont = new WritableFont(WritableFont.ARIAL, WritableFont.DEFAULT_POINT_SIZE, WritableFont.BOLD); 
				WritableCellFormat headFormat = new WritableCellFormat (headFont);
				Label label = new Label(seq?i+1:i, 0, heads[i], headFormat); 
				sheet.addCell(label);
				
				if (widths != null && widths[i].trim().length() != 0) {
					int w = Integer.parseInt(widths[i]);
					//设置列宽,如果设定的是负数或者0,就不做设置,就保持默认设置
					if (w > 0) sheet.setColumnView(seq?i+1:i, w);
				}
			}
			
			
			//写表体
			if (data != null && keys != null) {
				Iterator i = data.iterator();
				int j = 1;
				while (i.hasNext()) {
					//序号
					if (seq) {
						Label label = new Label(0, j, String.valueOf(j));
						sheet.addCell(label);
					}
					
					//表体
					Object o = i.next();
					if (o instanceof Map) {
						Map map = (Map)o;
						for (int k = 0; k < keys.length; k ++) {
							String value = (map.get(keys[k]) != null)?map.get(keys[k]).toString():"";
							Label label = new Label(seq?k+1:k, j, value); 
							sheet.addCell(label);
						}
					}
					j++;
				}
			} else {
				logger.warn("no export data or no export keys, check the list action or the tag config");
			}
			
			//写入并关闭
			workbook.write();
			workbook.close();
			
		} catch (IOException e) {
			logger.error("when build excel, IO Exception", e);
		} catch (RowsExceededException e) {
			logger.error("when build excel, RowsExceeded Exception", e);
		} catch (WriteException e) {
			logger.error("when write excel, WriteException", e);
		} 
	}

}
